<template>
    <header>可定制化流程设计</header>
    <main class="flow-engine-desgin__wrap">
        <nav class="flow-desgin__nav">
            <Node :node-list.camel="nodeType.list" @on-drag-end="onDragEnd"></Node>
        </nav>
        <div ref="flowEngineBodyRef" class="flow-desgin__body" id="flowEngineBody">
             
        </div>
    </main>
</template>

<script setup>
defineOptions({
    name: "FlowEngineDesgin"
})
import { dia, shapes, layout, linkTools } from "@joint/core"
import Node from "./components/Node.vue"
import * as nodeType from "./utils/node-config"
import { portConfig, portsIn, portsOut } from './utils/port'
import { useNaiveDiscrete } from "@/hooks/navie-ui"

const flowEngineBodyRef = ref(null)
const graph = ref(null)
const paper = ref(null)
const nodes = ref([])

const { message } = useNaiveDiscrete()

function onDragEnd({evt, oldC}) {
    const { left, top, width, height } = flowEngineBodyRef.value.getBoundingClientRect()
    const { originalEvent: { clientX, clientY }, item, oldIndex } = evt
    const { name, color } = nodeType.list[oldIndex]

    // 判断拖拽对象是否放到容器区域，否则不能生成节点
    if (clientX>left&&clientX<left+width&&clientY>top&&clientY&&clientY<top+height){

    } else {
        message.warning('请将元素拖拽到右侧编辑区域内', { duration: 3500 })
        return
    }

    // 创建容器节点
    const rect = new shapes.standard.Rectangle({
        position: {
            x: clientX - left,
            y: clientY - top,
        },
        size: { width: 180, height: 100 },
        attrs: {
            body: { fill: "#3B3561", rx: 6, ry: 5, stroke: 'none' },
            label: {
                text: '发起人自选  >',
                textAnchor: 'middle',
                refX: '0%',
                refY: '0%',
                xAlignment: 40, // 水平距离
                fill: '#fff'
            },
        },
        ports: {
            groups: {
                in: portsIn,
                out: portsOut
            }
        }
    })
    // 添加锚点
    rect.addPorts([
        {
            group: 'in',
            // attrs: { label: { text: 'part 1'}},
            args: { x: '0%', y: '40%' }
        },
        {
            group: 'in',
            // attrs: { label: { text: 'part 2'}}
        },
        {
            group: 'out',
            // attrs: { label: { text: 'part 1'}},
            args: { x: '100%', y: '40%' }
        },
        {
            group: 'out',
            // attrs: { label: { text: 'part 2'}},
            // args: { x: '0%', y: '0%' }
        },
    ])

    // 节点挂在到graph  paper.value.getArea()
    rect.addTo(graph.value)

    // 辅助文本
    const { position, size } = rect.attributes
    const rect2 = new shapes.standard.Rectangle({
        position: {
            x: position.x,
            y: position.y,
        },
        size: { width: size.width, height: 24},
        attrs: {
            body: { fill: color || "#FFDD4A", ry: 6, rx: 1, stroke: 'none' },
            label: {
                text: name,
                textAnchor: 'middle',
                fill: '#fff'
            }
        },
    })

    rect2.addTo(graph.value)
    // 绑定元素
    rect.embed(rect2)
    // 解除绑定元素
    // rect.unembed(rect2)
    // 子元素移动，父元素也跟着移动
    rect2.on("change:position", function(evt) {
        const { position, size } = rect2.attributes
        rect.set('position', { x: position.x, y: position.y})
    })
}

function createGraphs() {
    graph.value = new dia.Graph({}, { cellNamespace: shapes })
    paper.value = new dia.Paper({
        el: document.getElementById("flowEngineBody"),
        model: graph.value,
        width: '100%',
        height: '100%',
        gridSize: 10,
        drawGrid: true,
        background: {
            color: "#dde6ed",
        },
        cellViewNamespace: shapes,
        defaultLink: () => new shapes.standard.Link({
            attrs: {
                wrapper: {
                    cursor: 'default'
                }
            }
        }), // 默认链接配置
        linkPinning: false, // 禁止链接拖拽到空白区域
        defaultConnectionPoint: { name: 'boundary' },
        validateConnection: function(cellViewS, magnetS, cellViewT, magnetT, end, linkView) {
            // Prevent loop linking
            return (magnetS !== magnetT);
        }
    })
}

nextTick(() => {
    createGraphs()
})
</script>

<style lang="scss" src="./style.scss"></style>